#pragma once
#include "Sock.hpp"
#include<iostream>
#include <pthread.h>
#include<vector>
#include<functional>
#include<unistd.h>

namespace ns_tcpserver
{
    using func_t = std::function<void(int)>;

    class TcpServer;
    class ThreadData
    {
    public: 
        ThreadData(int sock,TcpServer* server)
        :_sock(sock)
        ,_server(server)
        {

        }
        ~ThreadData(){}
    public:
        int _sock;
        TcpServer* _server;
    };
    class TcpServer 
    {
    public:
        TcpServer(uint16_t& port,const std::string& ip="0.0.0.0")
        {
            _serversock=_sock.Socket();
            _sock.Bind(_serversock, port);
            _sock.Listen(_serversock);
        }
        void BindHandler(func_t callback)
        {
            _Func.push_back(callback);
        }
        void Execute(int sock)
        {
            for(auto& iter:_Func){
                iter(sock);
            }
        }
        static void* ThreadRoutine(void* args)
        {
            pthread_detach(pthread_self());
            ThreadData* td=static_cast<ThreadData*>(args);
            td->_server->Execute(td->_sock);
            close(td->_sock);
            return nullptr;
        }
        void Start(){
            while(true)
            {
                uint16_t client_port;
                std::string client_ip;
                //因为这里的TCP服务，所以在这里必须先与客户端建立起来联系
                int sock=_sock.Accept(_serversock, &client_port, &client_ip);
                if(sock == -1){
                    continue;
                }
                pthread_t tid;
                ThreadData* td=new ThreadData(sock,this);
                pthread_create(&tid, nullptr, ThreadRoutine, (void*)td);
            }
        }
        ~TcpServer(){

        }
    private:
        int _serversock;
        Sock _sock;
        std::vector<func_t>_Func;
    };
}
